package test.client.executor;

import test.client.support.thread.DefaultThreadManager;
import test.client.support.thread.ThreadManager;
import test.client.thread.ClientThread;
import test.client.thread.message.ClientSenderThread;
import test.client.thread.message.ClientPersistentLoginThread;
import test.configuration.ConfigFactory;
import test.domain.environment.MetaThread;

public class MessageClient extends Client {
	private final int maxCompanyCount = 1;
	private final int maxUserCount = 100;

	private final int maxMessageThread = 10;
	
	private final int maxPersistentLoginThread = 90;
//	private final int iterationLoginThreadCount = 90;
	
	private ThreadManager loginThreadManager = new DefaultThreadManager();
	
	public void execute() {
		// Initialize
		this.initialize(maxCompanyCount * maxMessageThread);
		
		// Start TimeCheckWorker thread
		this.startWatcher();
				
		// Start Persistent Login threads
		this.startLoginThreads();
		
		// Prepare message thread
		for (int i = 0; i < maxCompanyCount; i++) {
			int start = i * maxUserCount;
			int end = start + maxMessageThread;
			
			for (int j = start; j < end; j++) {
				ClientSenderThread client = new ClientSenderThread();
				this.prepare(client, j);
				client.setTo(this.getRecipient(client));
				
//				System.out.println("[" + client.getUsername() + "] To: " + this.getRecipient(client));
			}
		}
		
		// Run the thread
		this.start();
		
		// Wait until all message thread works are done.
		int count = 0;		
		try {
			while (!this.getThreadManager().isAllThreadDone() && count++ < 10) {
				try {
					log.debug("count: " + count);
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			if (count >= 10) {
				this.getThreadManager().printAllThreadStatus();
			}
			
			// Stop all persistent login threads
			this.stopLoginThreads();
		}
	}
	
	private void startLoginThreads() {
		MetaThread meta = ConfigFactory.getConfiguration().getMetaThread();
		meta.setMaxThreadCount(maxCompanyCount * maxPersistentLoginThread);
		this.loginThreadManager.initialize(meta);
		
		for (int i = 0; i < maxCompanyCount; i++) {
			int start = i * maxUserCount + maxMessageThread;
			int end = start + maxPersistentLoginThread;
			
			for (int j = start; j < end; j++) {
				// Prepare client thread
				ClientPersistentLoginThread login = new ClientPersistentLoginThread();
				this.prepare(login, j, false);
				this.loginThreadManager.put(login);
			}
		}
		
		// Run login threads
		this.loginThreadManager.start();
	}
	
	private void stopLoginThreads() {
		System.out.println("stops all login threads...");
		this.loginThreadManager.stop();
		
		log.info(this.loginThreadManager.getMaxThreadCount() + " login threads have been stopped.");
	}
	
	private String getRecipient(ClientThread client) {
		String username = client.getUsername();
		String to = "";
		
		if (username.endsWith("0")) to = username.substring(0, 9) + "1";
		else if (username.endsWith("1")) to = username.substring(0, 9) + "0";
		else if (username.endsWith("2")) to = username.substring(0, 9) + "3";
		else if (username.endsWith("3")) to = username.substring(0, 9) + "2";
		else if (username.endsWith("4")) to = username.substring(0, 9) + "5";
		else if (username.endsWith("5")) to = username.substring(0, 9) + "4";
		else if (username.endsWith("6")) to = username.substring(0, 9) + "7";
		else if (username.endsWith("7")) to = username.substring(0, 9) + "6";
		else if (username.endsWith("8")) to = username.substring(0, 9) + "9";
		else if (username.endsWith("9")) to = username.substring(0, 9) + "8";
		else return null;
		
		return to + "@openfire";
	}
	
	public static void main(String[] args) {
		Client client = new MessageClient();
		
		client.execute();
		
//		ClientThread thread= new ClientMessageThread();
//		thread.setUsername("user000106");
//		
//		System.out.println(client.getRecipient(thread));
	}
}
